#! /usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2011 BidiX (http://bidix.info)
#
#   Licensed under the Apache License, Version 2.0 (the "License");
#   you may not use this file except in compliance with the License.
#   You may obtain a copy of the License at
#
#	 http://www.apache.org/licenses/LICENSE-2.0
#
#   Unless required by applicable law or agreed to in writing, software
#   distributed under the License is distributed on an "AS IS" BASIS,
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#   See the License for the specific language governing permissions and
#   limitations under the License.
#
"""
Implementation of the user interface.

"""
import re
import markdown
import config
import notewiki.model
import md_extensions
from google.appengine.api import users 
import cgi
from HTMLParser import HTMLParser
from re import sub

def unescape(s, quote=None):
	"""cgi module provide an escape function but no unescape"""
	s = s.replace("&lt;", "<")
	s = s.replace("&gt;", ">")
	if quote:
		s = s.replace("&quot;", '"')
	s = s.replace("&amp;", "&") # Must be done last!
	return s
	
def render_str(s):
	"""Render a string. If `s` is None render ''"""
	if s:
		return s
	else:
		return ''
	
def render_user(user):
	"""Render a user as his wikiname"""
	if user:
		return notewiki.model.wikiname(user)
	else:
		return ''
		
def wikilinks_element_builder(label, anchor, title, base_url, end_url, article):
	""" 
	Return elements for Building a Notewiki Wikilink 
	
	See: :class:`notewiki.ui.md_extensions.WikiLinkExtension`
	"""
	name = label
	if label == '' and article:
		name = article.name
	if label[0:2] == './' and article:
		name = article.folder+'/'+label[2:]
	elif label[0:3] == '../' and article:
		name = notewiki.model.dirname(article.folder)+label[2:]
	elif label[0:2] == '+/' and article:
		name = article.name+'/'+label[2:]
	url = '%s%s%s'%(base_url,name+anchor,end_url)
	text = notewiki.model.Article.title_for_name(name)
	if text:
		url_exists = True
	else:
		text = name
		if name[len(name)-1] == '/': 
			url_exists = True
		else:
			url_exists = False
	if not title:
		title = text
	return (url, title, name, url_exists)

def text_to_html(text, article=None, base_url='/'):
	"""
	Apply transclusion and render a text in Markdown syntax to html.
	
	First recusively transcludes all articles specified.
	
	Next uses Python-Mardown with some Makdown extensions and Notewiki extensions. 
	See `link notewiki/doc/references/syntax <http://notewiki.bidix.info/notewiki/doc/references/syntax>`_.
 and :mod:`notewiki.ui.md_extensions`
 
	"""
	if text:
		#
		# recursive transclusion
		# 
		t = re.compile('\{\{(.*?)\}\}')
		m = t.search(text)
		while m:
			article_name = m.group(1)
			article = notewiki.model.Article.get_by_name(article_name)
			if article:
				text = text[:m.start()] + article.text + text[m.end():]
			else:
				text = text[:m.start()] + text[m.end():]	
			m = t.search(text)
		#
		# escaping transclusion syntax
		#	
		et = re.compile('\\\{\\\{(.*?)\}\}')
		m = et.search(text)
		while m:
			s = m.group(1)
			text = text[:m.start()] +'{{'+ s +'}}'+ text[m.end():]
			m = et.search(text)
		#
		# Markdown conversion 
		#				
		wikilink_extension_configs = [
										('base_url', base_url),
										('end_url', ''),
										('element_builder', wikilinks_element_builder),
										('context', article)
										]
		md = markdown.Markdown(
		extensions = [
					'abbr',
					'attr_list',
					'def_list',
					'fenced_code',
					'footnotes',
					'tables', 
					'codehilite',
					'headerid',
					'toc',
					md_extensions.WikiLinkExtension(wikilink_extension_configs),
					md_extensions.DelExtension(),
					md_extensions.HilitedExtension(),
					md_extensions.InlineExtension(),
					])
		html = md.convert(text)
	else:
		html=""
	return html

def format_user(current_url, base_url='/'):
	"""return a <div> with user infos and login, logout url"""
	current_user = users.get_current_user()
	response = ""
	if current_user:
		username = notewiki.model.wikiname(current_user)
		if users.is_current_user_admin():
			response += "Admin: "
		else:
			response += "User: "
		response += "<a href=\"%susers/%s\">%s</a>"%(base_url, username, username)
		response += " | <a href=\"%s\">logout</a>"%users.create_logout_url(current_url)
	else:
		response += "<a href=\"%s\">login</a>"%users.create_login_url(current_url)
	response += ""
	return response

class _DeHTMLParser(HTMLParser):
	def __init__(self):
		HTMLParser.__init__(self)
		self.__text = []

	def handle_data(self, data):
		text = data.strip()
		if len(text) > 0:
			text = sub('[ \t\r\n]+', ' ', text)
			self.__text.append(text + ' ')

	def handle_starttag(self, tag, attrs):
		if tag == 'p':
			self.__text.append('\n\n')
		elif tag == 'br':
			self.__text.append('\n')

	def handle_startendtag(self, tag, attrs):
		if tag == 'br':
			self.__text.append('\n\n')

	def text(self):
		return ''.join(self.__text).strip()


def dehtml(html):
	"""
	Convert an html string to plain text string
	"""

	parser = _DeHTMLParser()
	parser.feed(html)
	parser.close()
	return parser.text()
